#include "mapmenu.h"

#include "application.h"

CMapMenu::CMapMenu(const path &szPath, float fX, float fY)
    : CMenu(fX, fY),
      m_szPath(szPath)
{
    if (! is_directory(szPath))
    {
        stringstream sstream;
        sstream << "CMapMenu::CMapMenu - "
                << "Path "
                << szPath
                << " is not a valid directory for maps";
        throw std::runtime_error(sstream.str());
    }

    int nYOffset(0);

    // Copy all maps from directory into vector
    for (directory_iterator pPath(m_szPath);
         pPath != directory_iterator(); ++pPath)
    {
        path szPathIterable(pPath->path());
        if (szPathIterable.extension() == ".bmm")
        {
            path szImagePath((szPathIterable.parent_path() / 
                szPathIterable.stem()).string() + ".png");
            if (exists(szImagePath))
            {
                szImagePath.make_preferred();
                CUISprite *pSprite(new CUISprite(szImagePath.generic_string()));
                CPanel *pPanel(CUI::getInstance()->getChild("background"));
                if (pPanel != nullptr)
                {
                    pSprite->hide();
                    pSprite->setMarginTop(200);
                    pSprite->setMarginLeft(300);
                    const float fNewHeight(250.0f);
                    pSprite->setScale(fNewHeight / pSprite->getWidth() * 1.5f, 
                        fNewHeight / pSprite->getHeight());
                    pPanel->addChild(szImagePath.stem().string(), pSprite);
                    m_arrImages.push_back(pSprite);
                }
                else
                {
                    // Can't add to something which isn't there, clean up the
                    // memory
                    delete pSprite;
                    m_arrImages.push_back(nullptr);
                }
            }
            else
            {
                m_arrImages.push_back(nullptr);
            }

            addOption(szPathIterable.stem().string(), 0, nYOffset);
            nYOffset += 50;
        }
    }
    addOption("Back", 0, nYOffset);

    setTitle("Choose a map", 0.0f, -50.0f);
}

void CMapMenu::onChange(COption *pOldOption, COption *pNewOption)
{
    if (pOldOption != pNewOption)
    {
        if (pOldOption->getIndex() < static_cast<signed int>(
            m_arrImages.size()))
        {
            CUISprite *pSprite(m_arrImages.at(pOldOption->getIndex()));
            if (pSprite != nullptr)
            {
                pSprite->hide();
            }
        }
        if (pNewOption->getIndex() < static_cast<signed int>(
            m_arrImages.size()))
        {
            CUISprite *pSprite(m_arrImages.at(pNewOption->getIndex()));
            if (pSprite != nullptr)
            {
                pSprite->show();
                pSprite->setRotationDegrees(rand() % 40 - 20.0f);
            }
        }
    }
}

void CMapMenu::onDeactivate()
{
    for (vector<CUISprite*>::iterator pSprite(m_arrImages.begin());
         pSprite != m_arrImages.end(); ++pSprite)
    {
        if ((*pSprite) != nullptr)
        {
            (*pSprite)->hide();
        }
    }
}

void CMapMenu::onActivate()
{
    while (getCurrentSelectionIndex() > 0)
    {
        decrementSelection();
    }
    int nSelectedIndex(getCurrentSelectionIndex());

    if (nSelectedIndex < static_cast<signed int>(m_arrImages.size()))
    {
        CUISprite *pSprite(m_arrImages.at(nSelectedIndex));
        if (pSprite != nullptr)
        {
            pSprite->show();
        }
    }
}

void CMapMenu::callSelected(unsigned char chKey)
{
    if (chKey == DIK_RIGHT || chKey == DIK_LEFT) return;
    setActive(false);
    COption *pOption(getCurrentOption());
    string szMapName(pOption->getOriginalText());
    if (szMapName == "Back")
    {
        CMenuContainer::getInstance()->getMenu("main_menu")->setActive(true);
    }
    else
    {
        CUI::getInstance()->getChild("background")->hide();
        szMapName = string("maps/") + szMapName + ".bmm";

        CMapContainer *pMaps(CMapContainer::getInstance());
        if (pMaps->isMapLoaded())
        {
            pMaps->unloadCurrentMap();
        }

        CMapLoader mapLoader;
        pMaps->setCurrentMap(mapLoader.loadMap(szMapName));

        CApplication::getInstance()->stopMusic();
    }

    FMOD::Channel *pChannel(nullptr);
    CSoundManager::getInstance()->getSound(
        "select.wav")->createNewChannel(&pChannel);
    pChannel->setPaused(false);
}